package main

import (
	"github.com/boltdb/bolt"
	"log"
)

type BlockChain struct {
	tip []byte //最新快hash值
	db  *bolt.DB
}

//BlockChainIterator 迭代器
type BlockChainIterator struct {
	currentHash []byte //遍历的最新区块Hash
	db          *bolt.DB
}

//NewBlockChin 构造函数
func NewBlockChin() *BlockChain {
	//1.创建db文件
	db, err := bolt.Open("leval2.db", 0600, nil)
	if err != nil {
		log.Fatal(err)
	}
	var tip []byte

	err = db.Update(func(tx *bolt.Tx) error {
		//2.创建bucket
		bucket, err := tx.CreateBucket([]byte("MyBucket"))
		if err != nil {
			return err
		}

		//3.将最新hash -》最新块数据
		block := NewGenesisBlock()
		//hash =>data(序列化)
		err = bucket.Put(block.Hash, block.Serialize())
		if err != nil {
			log.Fatal(err)
		}
		//4.记录tip值
		bucket.Put([]byte("last"), block.Hash)
		tip = block.Hash
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
	//需要创建创世块，加入区块链
	return &BlockChain{tip, db}
}

//AddBlock 交易挖矿
func (bc *BlockChain) AddBlock(data string) {
	//创建一个新区块
	block := NewBlock(data, bc.tip)
	err := bc.db.Update(func(tx *bolt.Tx) error {
		//2.获取bucket
		bucket:= tx.Bucket([]byte("MyBucket"))
		//3.将最新hash -》最新块数据
		block = NewGenesisBlock()
		//hash =>data(序列化)
		err := bucket.Put(block.Hash, block.Serialize())
		if err != nil {
			log.Fatal(err)
		}
		//4.记录tip值
		bucket.Put([]byte("last"), block.Hash)
		bc.tip = block.Hash
		return nil
	})
	if err !=nil{
		log.Fatal(err)
	}
}

//NewBlockChainIterator 创建迭代器
func (bc *BlockChain) NewBlockChainIterator() *BlockChainIterator {
	return &BlockChainIterator{bc.tip, bc.db}
}

func (bci *BlockChainIterator) PrevBlock() (*Block,bool) {
	var block *Block
    err :=bci.db.View(func(tx *bolt.Tx)error{
    	//获取bucket
    	bucket :=tx.Bucket([]byte("MyBucket"))
    	//获取序列化数据
    	data :=bucket.Get(bci.currentHash)
    	//反序列化
    	block =DeSerialize(data)
    	bci.currentHash =block.PrevHash //指向前一个区块的hash
    	return nil

	})
    if err !=nil{
		log.Fatal(err)
	}
    return block,len(block.PrevHash)>0
}
